<template>
  <div class="g-scrollList">
    <!-- 虚拟滚动 -->
    <div
      class="g-scrollList-wrapper"
      @scroll="handScroll"
      :style="{ height: boxHeight + 'px' }"
    >
      <ul :style="{ height: originData.length * itemHeight + 'px' }">
        <li v-for="i in dataList" :key="i" :style="getLiStyle">数字{{ i }}</li>
      </ul>
    </div>
  </div>
</template>

<script>
export default {
  name: 'g-scroll-list',
  data() {
    return {
      // 全部数据
      originData: [],
      // 显示行数
      rows: '',
      // 每行元素高度
      itemHeight: 32,
      // 外层容器高度
      boxHeight: 331,
      // 显示数据
      dataList: [],
      moveY: 0,
    }
  },
  computed: {
    getLiStyle() {
      const { moveY, itemHeight } = this
      return "transform:translateY("+moveY+"px);height:"+itemHeight+"px;lineHeight:"+itemHeight+"px"
    },
  },
  created() {
    this.originData = new Array(100).fill(1).map((val, index) => index + 1)
    this.rows = Math.ceil(this.boxHeight / this.itemHeight)
    this.dataList = this.originData.slice(0, this.rows)
  },
  methods: {
    /**
     * 虚拟滚动触发
     */
    handScroll(e) {
      const { itemHeight, rows } = this
      const scrollTop = e.target.scrollTop
      this.moveY = itemHeight * Math.floor(scrollTop / itemHeight)
      this.dataList = this.originData.slice(
        Math.floor(scrollTop / itemHeight),
        Math.floor(scrollTop / itemHeight) + rows,
      )
    }
  }
}
</script>

<style lang="scss" scoped>
.g-scrollList {
  &-wrapper {
    overflow-y: scroll;
    width: 150px;
    ul {
      margin: 0;
      li {
        list-style: none;
        text-align: center;
        box-sizing: content-box;
        border: 1px solid #b8b8b8;
        &:not(:last-child) {
          border-bottom: none;
        }
      }
    }
  }
}
</style>
